#include "StdAfx.h"
#include "VSModel.h"
#include "SearchManager.h"
#include "QueryManager.h"
#include "QueryTerm.h"
#include <algorithm>


VSModel::VSModel(SearchManager * pSM, QueryManager * pQM, std::string outFile):RankingModel(pSM, pQM, outFile)
{
	m_ofs.open(outFile);
}


VSModel::~VSModel(void)
{
	if(m_ofs.is_open() == true)
		m_ofs.close();
}


void VSModel::RankingQuery(unsigned int queryIndex, unsigned int printCount )
{
	QueryTerm *pQueryTerm = m_pQueryManager->GetQueryTerm(queryIndex);	
	
	if( pQueryTerm == 0 )
		return ;

	DocumentManager *pDocumentManager = m_pSearchManager->GetDocumentManager();

	// Get Query Term & Term Weight
	QueryTermMap queryTermMap = pQueryTerm->GetTermFrequency();
	QueryWeightMap queryTermWeightMap = pQueryTerm->GetTermWeight();
	
	std::map< unsigned int, float> docWeightMap;
	ScoreMap scoreMap;
	scoreMap.clear();

	docRanking.clear();

	for( QueryWeightMap::iterator it = queryTermWeightMap.begin(); it != queryTermWeightMap.end(); ++it )
	{
		IndexData* pData = m_pSearchManager->FindIndexData(it->first);
		while( pData != 0 )
		{
			unsigned int docIndex = pData->documentIndex;
			float queryWeight = it->second;
			docWeightMap[docIndex] += (queryWeight * queryWeight);

			double score = pData->weight * queryWeight;

			ScoreMap::iterator it = scoreMap.find(docIndex);
			if( it == scoreMap.end() )
				scoreMap.insert(ScoreMap::value_type(docIndex, score) );
			else
				it->second += score;

			pData = m_pSearchManager->NextIndexData();
		}
	}

	float NormalisedQueryWeight = pQueryTerm->GetNormalizedWeight();

	for ( ScoreMap::iterator iter = scoreMap.begin(); iter != scoreMap.end(); ++iter )
	{
		docRanking.push_back( std::make_pair( iter->first, iter->second / sqrt( docWeightMap[iter->first] * NormalisedQueryWeight) ) );
	}
		
	sort( docRanking.begin(), docRanking.end(), descending);

	this->DisplayResult(queryIndex, printCount);
	
}